import { Box, HStack, panda } from '@/styled-system/jsx'

interface CodeBlockProps {
  title: string
  lang: CodeLang
  children: React.ReactNode
  [key: string]: any
}

export const CodeBlock = (props: CodeBlockProps) => {
  const { title, lang, children, ...rest } = props

  const extLang = title.split('.').pop()
  const resolvedLang = extLang !== lang ? extLang : lang

  return (
    <Box
      {...rest}
      data-lang={lang}
      spaceY="0!"
      marginY="1.6em"
      rounded="10px"
      css={{
        '& pre.shiki': {
          roundedTop: '0!',
          roundedBottom: 'lg!',
          shadow: 'none!'
        }
      }}
    >
      <HStack
        bg="bg.muted"
        px="4"
        py="3"
        roundedTop="lg"
        borderBottomWidth="1px"
      >
        {resolvedLang && <CodeLangIcon type={resolvedLang} />}
        <Box as="p" textStyle="sm" fontFamily="mono">
          {title}
        </Box>
      </HStack>
      {children}
    </Box>
  )
}

type CodeLang =
  | 'tsx'
  | 'ts'
  | 'js'
  | 'jsx'
  | 'css'
  | 'json'
  | 'astro'
  | 'html'
  | 'bash'
  | 'vue-html'
  | 'hbs'

interface CodeLangIconProps {
  type: CodeLang | (string & {})
}

const Svg = panda('svg', {
  base: {
    boxSize: '1em',
    fontSize: 'md'
  }
})

const CodeLangIcon = (props: CodeLangIconProps) => {
  switch (props.type) {
    case 'tsx':
    case 'jsx':
      return (
        <Svg
          stroke="currentColor"
          fill="currentColor"
          strokeWidth="0"
          viewBox="0 0 512 512"
        >
          <path d="M410.66 180.72q-7.67-2.62-15.45-4.88 1.29-5.25 2.38-10.56c11.7-56.9 4.05-102.74-22.06-117.83-25-14.48-66 .61-107.36 36.69q-6.1 5.34-11.95 11-3.9-3.76-8-7.36c-43.35-38.58-86.8-54.83-112.88-39.69-25 14.51-32.43 57.6-21.9 111.53q1.58 8 3.55 15.93a320.85 320.85 0 0 0-17.77 5.6C48.46 198.9 16 226.73 16 255.59c0 29.82 34.84 59.72 87.77 77.85q6.44 2.19 13 4.07-2.13 8.49-3.77 17.17c-10 53-2.2 95.07 22.75 109.49 25.77 14.89 69-.41 111.14-37.31q5-4.38 10-9.25 6.32 6.11 13 11.86c40.8 35.18 81.09 49.39 106 34.93 25.75-14.94 34.12-60.14 23.25-115.13q-1.25-6.3-2.88-12.86 4.56-1.35 8.93-2.79c55-18.27 90.83-47.81 90.83-78-.02-29-33.52-57.01-85.36-74.9zm-129-81.08c35.43-30.91 68.55-43.11 83.65-34.39 16.07 9.29 22.32 46.75 12.22 95.88q-1 4.8-2.16 9.57a487.83 487.83 0 0 0-64.18-10.16 481.27 481.27 0 0 0-40.57-50.75q5.38-5.22 11.02-10.15zM157.73 280.25q6.51 12.6 13.61 24.89 7.23 12.54 15.07 24.71a435.28 435.28 0 0 1-44.24-7.13c4.24-13.72 9.46-27.97 15.56-42.47zm0-48.33c-6-14.19-11.08-28.15-15.25-41.63 13.7-3.07 28.3-5.58 43.52-7.48q-7.65 11.94-14.72 24.23t-13.58 24.88zm10.9 24.17q9.48-19.77 20.42-38.78 10.93-19 23.27-37.13c14.28-1.08 28.92-1.65 43.71-1.65s29.52.57 43.79 1.66q12.21 18.09 23.13 37t20.69 38.6Q334 275.63 323 294.73q-10.91 19-23 37.24c-14.25 1-29 1.55-44 1.55s-29.47-.47-43.46-1.38q-12.43-18.19-23.46-37.29t-20.48-38.76zM340.75 305q7.25-12.58 13.92-25.49a440.41 440.41 0 0 1 16.12 42.32 434.44 434.44 0 0 1-44.79 7.65q7.62-12.09 14.75-24.48zm13.72-73.07q-6.64-12.65-13.81-25-7-12.18-14.59-24.06c15.31 1.94 30 4.52 43.77 7.67a439.89 439.89 0 0 1-15.37 41.39zm-98.24-107.45a439.75 439.75 0 0 1 28.25 34.18q-28.35-1.35-56.74 0c9.33-12.34 18.88-23.79 28.49-34.18zM145.66 65.86c16.06-9.32 51.57 4 89 37.27 2.39 2.13 4.8 4.36 7.2 6.67A491.37 491.37 0 0 0 201 160.51a499.12 499.12 0 0 0-64.06 10q-1.83-7.36-3.3-14.82c-9.05-46.23-3.06-81.08 12.02-89.83zm-23.41 251.85q-6-1.71-11.85-3.71c-23.4-8-42.73-18.44-56-29.81-11.88-10.19-17.9-20.36-17.9-28.6 0-17.51 26.06-39.85 69.52-55q8.19-2.85 16.52-5.21a493.54 493.54 0 0 0 23.4 60.75 502.46 502.46 0 0 0-23.69 61.58zm111.13 93.67c-18.63 16.32-37.29 27.89-53.74 33.72-14.78 5.23-26.55 5.38-33.66 1.27-15.14-8.75-21.44-42.54-12.85-87.86q1.53-8 3.5-16a480.85 480.85 0 0 0 64.69 9.39 501.2 501.2 0 0 0 41.2 51c-2.98 2.93-6.03 5.75-9.14 8.48zm23.42-23.22c-9.72-10.51-19.42-22.14-28.88-34.64q13.79.54 28.08.54c9.78 0 19.46-.21 29-.64a439.33 439.33 0 0 1-28.2 34.74zm124.52 28.59c-2.86 15.44-8.61 25.74-15.72 29.86-15.13 8.78-47.48-2.63-82.36-32.72-4-3.44-8-7.13-12.07-11a484.54 484.54 0 0 0 40.23-51.2 477.84 477.84 0 0 0 65-10.05q1.47 5.94 2.6 11.64c4.81 24.3 5.5 46.28 2.32 63.47zm17.4-102.64c-2.62.87-5.32 1.71-8.06 2.53a483.26 483.26 0 0 0-24.31-60.94 481.52 481.52 0 0 0 23.36-60.06c4.91 1.43 9.68 2.93 14.27 4.52 44.42 15.32 71.52 38 71.52 55.43 0 18.6-29.27 42.74-76.78 58.52z"></path>
          <path d="M256 298.55a43 43 0 1 0-42.86-43 42.91 42.91 0 0 0 42.86 43z"></path>
        </Svg>
      )
    case 'ts':
      return (
        <Svg
          stroke="currentColor"
          fill="currentColor"
          strokeWidth="0"
          viewBox="0 0 24 24"
        >
          <path d="M19.24 3H4.76A1.76 1.76 0 0 0 3 4.76v14.48A1.76 1.76 0 0 0 4.76 21h14.48A1.76 1.76 0 0 0 21 19.24V4.76A1.76 1.76 0 0 0 19.24 3zm-5.8 10h-2.25v6.44H9.4V13H7.15v-1.46h6.29zm5.8 5.28a1.71 1.71 0 0 1-.67.74 3 3 0 0 1-1 .39 5.81 5.81 0 0 1-1.2.12 7 7 0 0 1-1.23-.11 4.52 4.52 0 0 1-1-.33v-1.71l-.06-.06h.06v.07a3.41 3.41 0 0 0 1 .54 3.06 3.06 0 0 0 1.13.2 2.58 2.58 0 0 0 .6-.06 1.47 1.47 0 0 0 .42-.17.75.75 0 0 0 .25-.25.69.69 0 0 0-.06-.74 1.24 1.24 0 0 0-.35-.33 3.12 3.12 0 0 0-.53-.3l-.67-.28a3.57 3.57 0 0 1-1.37-1 2 2 0 0 1-.46-1.33 2.16 2.16 0 0 1 .24-1.06 2.09 2.09 0 0 1 .66-.71 2.88 2.88 0 0 1 1-.42 5.11 5.11 0 0 1 1.19-.13 7 7 0 0 1 1.09.07 4.53 4.53 0 0 1 .88.23v1.65a2.42 2.42 0 0 0-.42-.24 3.58 3.58 0 0 0-.49-.17 3 3 0 0 0-.49-.1 2.45 2.45 0 0 0-.46 0 2.29 2.29 0 0 0-.56.06 1.54 1.54 0 0 0-.43.16.78.78 0 0 0-.26.25.63.63 0 0 0-.09.33.62.62 0 0 0 .1.35 1.19 1.19 0 0 0 .3.29 2.15 2.15 0 0 0 .46.28l.63.28a6.56 6.56 0 0 1 .84.42 2.65 2.65 0 0 1 .64.49 1.79 1.79 0 0 1 .42.63 2.48 2.48 0 0 1 .14.85 2.68 2.68 0 0 1-.25 1.08z"></path>
        </Svg>
      )
    case 'js':
      return (
        <Svg
          stroke="currentColor"
          fill="currentColor"
          strokeWidth="0"
          viewBox="0 0 24 24"
        >
          <path d="M3 3h18v18H3V3zm4.73 15.04c.4.85 1.19 1.55 2.54 1.55 1.5 0 2.53-.8 2.53-2.55v-5.78h-1.7V17c0 .86-.35 1.08-.9 1.08-.58 0-.82-.37-1.09-.8l-1.38.76zm5.98-.18c.5.98 1.38 1.7 2.8 1.7 1.6 0 2.64-.83 2.64-2.15 0-1.48-.9-2.04-2.4-2.75l-.42-.18c-.73-.31-1.04-.52-1.04-1.02 0-.41.31-.72.8-.72.5 0 .8.21 1.09.72l1.31-.87c-.55-.97-1.33-1.33-2.4-1.33-1.51 0-2.48.96-2.48 2.23 0 1.38.9 2.04 2.37 2.75l.42.18c.78.33 1.24.53 1.24 1.13 0 .48-.43.83-1.12.83-.76 0-1.22-.37-1.61-1.02l-1.2.83z"></path>
        </Svg>
      )
    case 'css':
      return (
        <Svg
          stroke="currentColor"
          fill="currentColor"
          strokeWidth="0"
          viewBox="0 0 512 512"
        >
          <path d="M480 32l-64 368-223.3 80L0 400l19.6-94.8h82l-8 40.6L210 390.2l134.1-44.4 18.8-97.1H29.5l16-82h333.7l10.5-52.7H56.3l16.3-82H480z"></path>
        </Svg>
      )
    case 'json':
      return (
        <Svg
          stroke="currentColor"
          fill="none"
          strokeWidth="2"
          viewBox="0 0 24 24"
          strokeLinecap="round"
          strokeLinejoin="round"
        >
          <path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"></path>
          <polyline points="14 2 14 8 20 8"></polyline>
          <path d="M10 12a1 1 0 0 0-1 1v1a1 1 0 0 1-1 1 1 1 0 0 1 1 1v1a1 1 0 0 0 1 1"></path>
          <path d="M14 18a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1 1 1 0 0 1-1-1v-1a1 1 0 0 0-1-1"></path>
        </Svg>
      )
    case 'astro':
      return (
        <Svg
          stroke="currentColor"
          fill="currentColor"
          strokeWidth="0"
          viewBox="0 0 30 30"
          translate="0 2px"
        >
          <path d="M7.70883 25.5523C6.35819 24.3134 5.9639 21.7103 6.52661 19.8245C7.50233 21.0135 8.85426 21.3901 10.2546 21.6027C12.4164 21.9308 14.5395 21.8081 16.5477 20.8166C16.7774 20.7031 16.9897 20.5522 17.2407 20.3993C17.4292 20.9478 17.4782 21.5017 17.4124 22.0653C17.2524 23.4381 16.5716 24.4985 15.4887 25.3023C15.0557 25.6238 14.5975 25.9112 14.1503 26.2144C12.7765 27.1462 12.4048 28.2387 12.921 29.828C12.9333 29.8667 12.9443 29.9054 12.972 29.9999C12.2705 29.6849 11.7582 29.2263 11.3678 28.6232C10.9554 27.9867 10.7592 27.2826 10.7489 26.5208C10.7437 26.1501 10.7437 25.776 10.694 25.4106C10.5727 24.5195 10.1559 24.1205 9.37051 24.0975C8.56451 24.0739 7.92694 24.5739 7.75787 25.3613C7.74497 25.4217 7.72625 25.4814 7.70754 25.5516L7.70883 25.5523Z"></path>
          <path d="M0 19.5103C0 19.5103 3.99947 17.5552 8.01012 17.5552L11.034 8.16461C11.1472 7.71047 11.4778 7.40185 11.8509 7.40185C12.2241 7.40185 12.5547 7.71047 12.6679 8.16461L15.6918 17.5552C20.4418 17.5552 23.7019 19.5103 23.7019 19.5103C23.7019 19.5103 16.9085 0.939907 16.8952 0.902648C16.7002 0.353607 16.3711 0 15.9273 0H7.77531C7.33154 0 7.01567 0.353607 6.80741 0.902648C6.79274 0.939204 0 19.5103 0 19.5103Z"></path>
        </Svg>
      )
    case 'html':
      return (
        <Svg
          stroke="currentColor"
          fill="currentColor"
          strokeWidth="0"
          viewBox="0 0 24 24"
        >
          <path d="M14 3h2.236l.025 3.81h1.763L18 9.81h-.789l.026 3.809H14v-1h2.789l-.026-2.809h-1.763l-.026-3.81H14V3z"></path>
          <path d="M6.236 3H8.47l-.026 3.81H10.21L6 9.81H5.21l.026 3.809H6v1H3.21L3.184 9.81H1.42L5.63 6.81H6.236V3z"></path>
          <path d="M20.764 7.19l-2.236 2.236L16.24 7.19l-1.414 1.414 2.236 2.236-2.236 2.236 1.414 1.414 2.236-2.236 2.236 2.236 1.414-1.414-2.236-2.236 2.236-2.236L20.764 7.19z"></path>
        </Svg>
      )
    case 'bash':
      return (
        <Svg
          stroke="currentColor"
          fill="none"
          strokeWidth="2"
          viewBox="0 0 24 24"
          strokeLinecap="round"
          strokeLinejoin="round"
        >
          <polyline points="4 17 10 11 4 5"></polyline>
          <line x1="12" x2="20" y1="19" y2="19"></line>
        </Svg>
      )

    case 'vue':
    case 'vue-html':
      return (
        <Svg viewBox="0 0 128 128">
          <path
            fill="#42b883"
            d="M78.8,10L64,35.4L49.2,10H0l64,110l64-110C128,10,78.8,10,78.8,10z"
          ></path>
          <path
            fill="#35495e"
            d="M78.8,10L64,35.4L49.2,10H25.6L64,76l38.4-66H78.8z"
          ></path>
        </Svg>
      )
    case 'hbs':
      return (
        <Svg
          stroke="#F0772B"
          fill="#F0772B"
          strokeWidth="0"
          viewBox="0 0 32 32"
        >
          <path d="M3.34 15.658c.282-.232.488-.543.59-.893.206-.538-.057-1.14-.59-1.356-1.733-.878-2.852.686-3.014 1.05s-.448.942-.267 2.26.817 2.535 2.806 3.014c1.903.442 3.9.21 5.65-.66l5.88-2.452a7.21 7.21 0 0 1 1.661-.207V14.41a4.6 4.6 0 0 0-4.453-2.343c-3.176.25-4.438 1.884-5.2 2.584s-2.207 2.35-3.168 2.06-1.232-1.477-.893-1.842.606-.3.817 0c.13.242.194.513.188.787z"></path>
          <path d="M28.66 15.658c-.282-.232-.488-.543-.59-.893-.206-.538.057-1.14.59-1.356 1.733-.878 2.852.686 3.014 1.05s.448.942.267 2.26-.817 2.535-2.806 3.014c-1.903.442-3.9.21-5.65-.66l-5.88-2.452a7.21 7.21 0 0 0-1.661-.207V14.41a4.6 4.6 0 0 1 4.453-2.343c3.176.25 4.438 1.884 5.2 2.584s2.207 2.35 3.168 2.06 1.232-1.477.893-1.842-.606-.3-.817 0c-.13.242-.194.513-.188.787z"></path>
        </Svg>
      )
    default:
      return (
        <Svg
          stroke="currentColor"
          fill="none"
          strokeWidth="2"
          viewBox="0 0 24 24"
          strokeLinecap="round"
          strokeLinejoin="round"
        >
          <path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path>
          <polyline points="13 2 13 9 20 9"></polyline>
        </Svg>
      )
  }
}
